﻿using NFine.Code;
using NFine.Data;
using NFine.Domain.Entity.BusinessManage;
using NFine.Domain.Entity.SystemManage;
using NFine.Domain.IRepository.SystemManage;
using NFine.Repository.BusinessManage;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Linq.Expressions;
using System.Text.RegularExpressions;
using System.Transactions;

namespace NFine.Repository.SystemManage
{
    public class UserRepository : RepositoryBase<UserEntity>, IUserRepository
    {
        #region 其他业务功能

        public void DeleteForm(string keyValue)
        {

            using (var db = new RepositoryBase().BeginTrans())
            {
                db.Delete<UserEntity>(t => t.F_Id == keyValue);
                db.Delete<UserLogOnEntity>(t => t.F_UserId == keyValue);
                db.Commit();
            }
        }
        public void SubmitForm(UserEntity userEntity, UserLogOnEntity userLogOnEntity, string keyValue)
        {
            using (var db = new RepositoryBase().BeginTrans())
            {
                if (!string.IsNullOrEmpty(keyValue))
                {
                    db.Update(userEntity);
                }
                else
                {
                    userLogOnEntity.F_Id = userEntity.F_Id;
                    userLogOnEntity.F_UserId = userEntity.F_Id;
                    userLogOnEntity.F_UserSecretkey = Md5.md5(Common.CreateNo(), 16).ToLower();
                    userLogOnEntity.F_UserPassword = Md5.md5(DESEncrypt.Encrypt(Md5.md5(userLogOnEntity.F_UserPassword, 32).ToLower(), userLogOnEntity.F_UserSecretkey).ToLower(), 32).ToLower();
                    db.Insert(userEntity);
                    db.Insert(userLogOnEntity);
                }
                db.Commit();
            }
        }

        public void SubmitRePassword(string type, string old, string newpass)
        {
            using (var db = new RepositoryBase().BeginTrans())
            {
                var loginId = OperatorProvider.Provider.GetCurrent().UserId;
                UserLogOnRepository usR = new UserLogOnRepository();
                UserLogOnEntity userEntity = usR.FindEntity(loginId);
                if (type == "pwd")
                {
                    var told = Md5.md5(DESEncrypt.Encrypt(Md5.md5(old, 32).ToLower(), userEntity.F_UserSecretkey).ToLower(), 32).ToLower();
                    if (told != userEntity.F_UserPassword)
                        throw new Exception("旧密码输入有误");
                    userEntity.F_UserPassword = Md5.md5(DESEncrypt.Encrypt(Md5.md5(newpass, 32).ToLower(), userEntity.F_UserSecretkey).ToLower(), 32).ToLower();
                }
                else
                {
                    var told = Md5.md5(DESEncrypt.Encrypt(Md5.md5(old, 32).ToLower(), userEntity.F_UserSecretkey).ToLower(), 32).ToLower();
                    if (told != userEntity.F_SecPassword)
                        throw new Exception("旧密码输入有误");
                    userEntity.F_SecPassword = Md5.md5(DESEncrypt.Encrypt(Md5.md5(newpass, 32).ToLower(), userEntity.F_UserSecretkey).ToLower(), 32).ToLower();
                }
                db.Update(userEntity);
                db.Commit();
            }
        }

        public void SubmitMember(UserEntity userEntity, string keyValue)
        {
            using (var db = new RepositoryBase().BeginTrans())
            {
                UserRepository usR = new UserRepository();
                UserEntity Ue = usR.FindEntity(keyValue);
                Ue.F_MobilePhone = userEntity.F_MobilePhone;
                Ue.F_AccountName = userEntity.F_AccountName;
                Ue.F_BankAccount = userEntity.F_BankAccount;
                Ue.F_Bank = userEntity.F_Bank;
                Ue.F_BankAddre = userEntity.F_BankAddre;
                Ue.F_Address = userEntity.F_Address;
                db.Update(Ue);
                db.Commit();
            }
        }

        public void Recharge(UserEntity userEntity)
        {
            using (var db = new RepositoryBase().BeginTrans())
            {
                Trigger trigger = new Trigger()
                {
                    Time = System.DateTime.Now,
                    UserID = OperatorProvider.Provider.GetCurrent().UserId
                };
                D_SalaryEntity salaryEntity = db.FindEntity<D_SalaryEntity>(userEntity.F_Id);
                salaryEntity.Amount=salaryEntity.Amount+ userEntity.F_MemberMoney.Value;

                var history = new D_SalaryHistoryEntity(Common.GuId(), userEntity.F_Id, SalaryChangeType.TypeValues.用户充值, userEntity.F_MemberMoney.Value, trigger, D_SalaryAccountType.Amount);
                db.Update(salaryEntity);
                db.Insert(history);
                db.Commit();
            }
        }

        public void FRecharge(UserEntity userEntity)
        {
            using (var db = new RepositoryBase().BeginTrans())
            {
                Trigger trigger = new Trigger()
                {
                    Time = System.DateTime.Now,
                    UserID = OperatorProvider.Provider.GetCurrent().UserId
                };
                D_SalaryEntity salaryEntity = db.FindEntity<D_SalaryEntity>(userEntity.F_Id);
                salaryEntity.Amount = salaryEntity.Amount - userEntity.F_MemberMoney.Value;
                if (salaryEntity.Amount < 0)
                    throw new Exception("用户账户余额不足，扣费失败");

                var history = new D_SalaryHistoryEntity(Common.GuId(), userEntity.F_Id, SalaryChangeType.TypeValues.用户扣费, -userEntity.F_MemberMoney.Value, trigger, D_SalaryAccountType.Amount,userEntity.F_Description);
                db.Update(salaryEntity);
                db.Insert(history);
                db.Commit();
            }
        }

        public void SubTransfer(UserEntity userEntity)
        {
            var loginId = OperatorProvider.Provider.GetCurrent().UserId;
            var expression = ExtLinq.True<UserEntity>();
            expression = expression.And(t => t.F_Account == userEntity.F_Account);
            expression = expression.And(t => t.F_IsAdministrator == false);
            expression = expression.And(t => t.F_EnabledMark == true);
            UserRepository Usr = new UserRepository();
            UserEntity entity = Usr.FindEntity(loginId);
            UserEntity entity1 = Usr.FindEntity(expression);
            if (entity1 == null)
                throw new Exception("账户不存在或已停用!");
            using (var db = new RepositoryBase().BeginTrans())
            {
                entity.F_MemberMoney = entity.F_MemberMoney - userEntity.F_MemberMoney;
                if (entity.F_MemberMoney < 0)
                    throw new Exception("账户余额不足,转账失败!");
                entity1.F_MemberMoney = entity1.F_MemberMoney + userEntity.F_MemberMoney;
                D_MemberCharge memberEntity = new D_MemberCharge();
                memberEntity.Create();
                memberEntity.F_Action = "会员转账";
                memberEntity.F_Remark = entity.F_Account + "向" + entity1.F_Account + "进行转账，转账金额为:" + userEntity.F_MemberMoney + "元";
                memberEntity.F_UserId = entity.F_Id;
                memberEntity.F_UserName = entity.F_Account;
                memberEntity.F_MemberId = entity1.F_Id;
                memberEntity.F_MemberName = entity1.F_Account;
                db.Update(entity);
                db.Update(entity1);
                db.Insert(memberEntity);
                db.Commit();
            }
        }

        public void SubmitMemberForm(UserEntity userEntity, UserLogOnEntity userLogOnEntity, string GoodIds, string keyValue)
        {
            using (var db = new RepositoryBase().BeginTrans())
            {
                if (!string.IsNullOrEmpty(keyValue))
                {
                    db.Update(userEntity);
                }
                else
                {
                    decimal allMoney = 0;
                    userLogOnEntity.F_Id = userEntity.F_Id;
                    userLogOnEntity.F_UserId = userEntity.F_Id;
                    userLogOnEntity.F_UserSecretkey = Md5.md5(Common.CreateNo(), 16).ToLower();
                    userLogOnEntity.F_UserPassword = Md5.md5(DESEncrypt.Encrypt(Md5.md5(userLogOnEntity.F_UserPassword, 32).ToLower(), userLogOnEntity.F_UserSecretkey).ToLower(), 32).ToLower();
                    if (OperatorProvider.Provider.GetCurrent().IsMember)
                        userLogOnEntity.F_SecPassword = Md5.md5(DESEncrypt.Encrypt(Md5.md5(userLogOnEntity.F_SecPassword, 32).ToLower(), userLogOnEntity.F_UserSecretkey).ToLower(), 32).ToLower();
                    userEntity.F_IsAdministrator = false;
                    userEntity.F_EnabledMark = true;
                    db.Insert(userEntity);
                    db.Insert(userLogOnEntity);
                    foreach (var id in GoodIds.Split(','))
                    {
                        D_GoodsRepository InR = new D_GoodsRepository();
                        D_GoodsEntity goodsEntity = InR.FindEntity(id);
                        D_IndentEntity indentEntity = new D_IndentEntity();
                        indentEntity.Create();
                        indentEntity.D_M_F_ID = userEntity.F_Id;
                        indentEntity.D_G_F_ID = id;
                        indentEntity.F_Nums = 1;
                        indentEntity.F_OrderDate = System.DateTime.Now;
                        indentEntity.F_OrderType = "0";
                        indentEntity.F_MemName = userEntity.F_RealName;
                        indentEntity.F_MemAccount = userEntity.F_AccountName;
                        indentEntity.F_MemTel = userEntity.F_MobilePhone;
                        indentEntity.F_OrderAddress = userEntity.F_Address;
                        indentEntity.F_CreatorTime = indentEntity.F_OrderDate;
                        indentEntity.F_CreatorUserId = OperatorProvider.Provider.GetCurrent().UserId;
                        indentEntity.F_EnabledMark = false;
                        indentEntity.F_Name = goodsEntity.F_Name;
                        indentEntity.F_Price = goodsEntity.F_Price;
                        indentEntity.F_Inte = goodsEntity.F_Inte;
                        indentEntity.F_Spec = goodsEntity.F_Spec;
                        indentEntity.F_Summary = goodsEntity.F_Summary;
                        allMoney = allMoney + goodsEntity.F_Price.SafeValue();
                        db.Insert(indentEntity);
                    }
                    UserRepository usR = new UserRepository();
                    var LoginId = OperatorProvider.Provider.GetCurrent().UserId;
                    UserEntity Ue = usR.FindEntity(LoginId);
                    Ue.F_MemberMoney = Ue.F_MemberMoney - allMoney;
                    if (Ue.F_MemberMoney < 0)
                    {
                        throw new Exception("账户余额不足,请先充值");
                    }
                    db.Update(Ue);
                }
                db.Commit();
            }
        }
        
        #endregion

        #region 注册新会员

        public void RegisterNewUserCore(UserEntity registUser, UserLogOnEntity userLogOnEntity, string GoodIds)
        {
            var Nums= GoodIds.Split(',');
            if(Nums.Length != 1)
                throw new Exception("只能选择一个商品");
            using (var scope = new TransactionScope(TransactionScopeOption.Required, new TransactionOptions { IsolationLevel = IsolationLevel.ReadUncommitted }))
            {
                registUser.F_Id = Common.GuId();
                registUser.F_EnabledMark = true;
                registUser.F_IsAdministrator = false;
                registUser.F_MemberMoney = 0;
                registUser.CurrentManagerType = 0;
                registUser.CumulativePoints = 0;

                userLogOnEntity.F_Id = registUser.F_Id;
                userLogOnEntity.F_UserId = registUser.F_Id;
                userLogOnEntity.F_UserSecretkey = Md5.md5(Common.CreateNo(), 16).ToLower();
                userLogOnEntity.F_UserPassword = Md5.md5(DESEncrypt.Encrypt(Md5.md5(userLogOnEntity.F_UserPassword, 32).ToLower(), userLogOnEntity.F_UserSecretkey).ToLower(), 32).ToLower();

                Trigger trigger = new Trigger()
                {
                    Time = registUser.F_CreatorTime.Value,
                    UserID = registUser.F_Id
                };
                var _context = new RepositoryBase().Dbcontext;


                var rObj = _context.Set<UserEntity>()
                    .Join(_context.Set<D_SalaryEntity>(), u => u.F_Id, s => s.ID, (User, Salary) => new { User, Salary })
                    .FirstOrDefault(obj => obj.User.F_Id == registUser.ReferenceID);
                var rUser = rObj.User;
                AppendUserAmount(rUser, rObj.Salary);
                if (rUser.RCount >= 2)
                {
                    throw new Exception("每个ID只允许推荐2个新ID！");
                }
                //修改行政区域,表示是否已经是被作为代理使用
                if (registUser.ProxyType != 0)
                {
                    if(string.IsNullOrEmpty(registUser.ProxyCode))
                        throw new Exception("请选择需要代理的地区！");
                    AreaEntity areaEntity =_context.Set<AreaEntity>().FirstOrDefault(u => u.F_Id == registUser.ProxyCode);
                    if(areaEntity.IsUsed==1)
                        throw new Exception("该地区已有代理,不能再申请！");
                    if (registUser.ProxyType == 1 && rUser.D_Amount < SalaryChangeType.TypeValues.省级代理)
                    {
                        throw new Exception("账户余额不足,请先充值！省级代理需要" + SalaryChangeType.TypeValues.省级代理 + "元");
                    }
                    else if (registUser.ProxyType == 2 && rUser.D_Amount < SalaryChangeType.TypeValues.市级代理)
                    {
                        throw new Exception("账户余额不足,请先充值！市级代理需要" + SalaryChangeType.TypeValues.市级代理 + "元");
                    }
                    else if (registUser.ProxyType == 3 && rUser.D_Amount < SalaryChangeType.TypeValues.区县级代理)
                    {
                        throw new Exception("账户余额不足,请先充值！区县级代理需要" + SalaryChangeType.TypeValues.区县级代理 + "元");
                    }

                    areaEntity.IsUsed = 1;
                    _context.Entry<AreaEntity>(areaEntity).State = System.Data.Entity.EntityState.Modified;
                }
                //-----------------------------------------------------
                //-----① 登陆人推荐人数+1,将新组tjrID员注册信息写入BS_User,并将其信息写入组内
                rUser.RCount++;
                _context.Entry<UserEntity>(rUser).State = System.Data.Entity.EntityState.Modified;
                registUser.CurrentGroupID = rUser.CurrentGroupID;
                registUser.RCount = 0;
                //增加薪金表
                var salary = new D_SalaryEntity(registUser.F_Id);

                _context.Set<UserEntity>().Add(registUser);
                _context.Set<UserLogOnEntity>().Add(userLogOnEntity);
                /* 订单相关的代码 */
                {
                    D_GoodsEntity goodsEntity = _context.Set<D_GoodsEntity>().FirstOrDefault(g => g.F_Id == GoodIds);
                    if (goodsEntity == null)
                        throw new Exception("未选择商品！");
                    if (rUser.D_Amount < goodsEntity.F_Price.SafeValue())
                    {
                        throw new Exception("账户余额不足,请先充值！");
                    }
                    D_IndentEntity indentEntity = new D_IndentEntity();
                    indentEntity.Create();
                    indentEntity.D_M_F_ID = registUser.F_Id;
                    indentEntity.D_G_F_ID = GoodIds;
                    indentEntity.F_Nums = 1;
                    indentEntity.F_OrderDate = trigger.Time;
                    indentEntity.F_OrderType = "0";
                    indentEntity.F_MemName = registUser.F_RealName;
                    indentEntity.F_MemAccount = registUser.F_AccountName;
                    indentEntity.F_MemTel = registUser.F_MobilePhone;
                    indentEntity.F_OrderAddress = registUser.F_Address;
                    indentEntity.F_CreatorTime = indentEntity.F_OrderDate;
                    indentEntity.F_CreatorUserId = registUser.ReferenceID;
                    indentEntity.F_EnabledMark = false;
                    indentEntity.F_Name = goodsEntity.F_Name;
                    indentEntity.F_Price = goodsEntity.F_Price;
                    indentEntity.F_Inte = goodsEntity.F_Inte;
                    indentEntity.F_Spec = goodsEntity.F_Spec;
                    indentEntity.F_Summary = goodsEntity.F_Summary;
                    _context.Set<D_IndentEntity>().Add(indentEntity);

                    rObj.Salary.Amount -= SalaryChangeType.TypeValues.公司进入一个点位;
                    {
                        var history = new D_SalaryHistoryEntity(Common.GuId(), registUser.ReferenceID, nameof(SalaryChangeType.TypeValues.公司进入一个点位), -SalaryChangeType.TypeValues.公司进入一个点位, trigger, D_SalaryAccountType.Amount);
                        var account = new D_AccountEntity(Common.GuId(), registUser.ReferenceID, nameof(SalaryChangeType.TypeValues.公司进入一个点位), SalaryChangeType.TypeValues.公司进入一个点位, trigger, D_SalaryAccountType.Amount, history.ID, true);
                        _context.Set<D_SalaryHistoryEntity>().Add(history); //新增薪酬历史
                        _context.Set<D_AccountEntity>().Add(account);//新增支出记录
                        _context.SaveChanges();
                    }
                    //是否未代理，计算代理推荐奖励
                    if (registUser.ProxyType != 0)
                    {
                        decimal allmoney = 0;
                        int sendPonts = 0;
                        string allName = "";
                        string sendPontsStr = "";
                        string tuijianStr = "";

                        switch (registUser.ProxyType)
                        {
                            case 1:
                                allmoney = SalaryChangeType.TypeValues.省级代理;
                                sendPonts = 15;
                                allName = nameof(SalaryChangeType.TypeValues.省级代理);
                                sendPontsStr = SalaryChangeType.TypeValues.省代理赠送15个点位;
                                tuijianStr = SalaryChangeType.TypeValues.省代理推荐奖励;
                                break;
                            case 2:
                                allmoney = SalaryChangeType.TypeValues.市级代理;
                                sendPonts = 7;
                                allName = nameof(SalaryChangeType.TypeValues.市级代理);
                                sendPontsStr = SalaryChangeType.TypeValues.市代理赠送7个点位;
                                tuijianStr = SalaryChangeType.TypeValues.市代理推荐奖励;
                                break;
                            case 3:
                                allmoney = SalaryChangeType.TypeValues.区县级代理;
                                sendPonts = 7;
                                allName = nameof(SalaryChangeType.TypeValues.区县级代理);
                                sendPontsStr = SalaryChangeType.TypeValues.区县代理赠送7个点位;
                                tuijianStr = SalaryChangeType.TypeValues.区县代理推荐奖励;
                                break;
                            default:
                                break;
                        }
                        
                        decimal 代理赠送点位金额 = (SalaryChangeType.TypeValues.公司进入一个点位 * sendPonts);
                        decimal 剩余金额 = allmoney - (SalaryChangeType.TypeValues.公司进入一个点位 * (sendPonts + 1));
                        decimal 奖励推荐人的金额 = allmoney * 0.1M;
                        rObj.Salary.Amount -= 代理赠送点位金额;
                        rObj.Salary.Amount -= 剩余金额;
                        rObj.Salary.Amount += 奖励推荐人的金额;
                        salary.Amount += 代理赠送点位金额;
                        //_context.Entry<D_SalaryEntity>(salary).State = System.Data.Entity.EntityState.Modified;
                        {
                            //①赠送15个点位
                            var sdhc1 = new D_SalaryHistoryEntity(Common.GuId(), registUser.ReferenceID, sendPontsStr, -代理赠送点位金额, trigger, D_SalaryAccountType.Amount);
                            var sdhs1 = new D_SalaryHistoryEntity(Common.GuId(), registUser.F_Id, sendPontsStr, 代理赠送点位金额, trigger, D_SalaryAccountType.Amount);
                            _context.Set<D_SalaryHistoryEntity>().Add(sdhc1);
                            _context.SaveChanges();
                            _context.Set<D_SalaryHistoryEntity>().Add(sdhs1);
                            _context.SaveChanges();
                        }
                        {
                            //②将剩余金额转入公司账目
                            var sdhc2 = new D_SalaryHistoryEntity(Common.GuId(), registUser.ReferenceID, allName, -剩余金额, trigger, D_SalaryAccountType.Amount);
                            var daes2 = new D_AccountEntity(Common.GuId(), registUser.ReferenceID, allName, 剩余金额, trigger, D_SalaryAccountType.Amount, sdhc2.ID, true);
                            _context.Set<D_SalaryHistoryEntity>().Add(sdhc2);
                            _context.SaveChanges();
                            _context.Set<D_AccountEntity>().Add(daes2);
                            _context.SaveChanges();
                        }
                        {
                            //③给推荐人奖励
                            var sdhs3 = new D_SalaryHistoryEntity(Common.GuId(), registUser.ReferenceID, tuijianStr, 奖励推荐人的金额, trigger, D_SalaryAccountType.Amount);
                            var daec3 = new D_AccountEntity(Common.GuId(), registUser.ReferenceID, tuijianStr, -奖励推荐人的金额, trigger, D_SalaryAccountType.Amount, sdhs3.ID, false);
                            _context.Set<D_SalaryHistoryEntity>().Add(sdhs3);
                            _context.SaveChanges();
                            _context.Set<D_AccountEntity>().Add(daec3);
                            _context.SaveChanges();
                        }
                    }
                }
                _context.Set<D_SalaryEntity>().Add(salary);
                _context.Entry<D_SalaryEntity>(rObj.Salary).State = System.Data.Entity.EntityState.Modified;
                _context.SaveChanges();

                /* 订单代码结束 */
                
                D_GroupMemberEntity newMemberUser = new D_GroupMemberEntity()
                {
                    ID = Common.GuId(),
                    GroupID = registUser.CurrentGroupID,
                    MemberID = registUser.F_Id,
                    MemberName = registUser.F_Account,
                    OrderID = 99,
                    PromotionTime = registUser.F_CreatorTime,
                    Amount = 0,
                    ManagerCount = 0,
                    GroupStatus = 3,
                    GroupStatusText = "新组员",
                    IsOperator = false,
                    User = registUser
                };

                //计算区域代理分成
                AreaProxy(_context, trigger, registUser);
                //计算管理奖并增加点位数
                BonusAndAddPoints(_context, trigger, registUser.ReferenceID);
                //将点位添加尽新消费组
                AddMemberToGroup(_context, trigger, newMemberUser);
                //计算复投账户
                RepeatAmount(_context, trigger, registUser);
                //提升管理者身份
                //JinshengManager(_context, ManagerType.黄金董事, registUser);

                scope.Complete();
            }
        }

        private static D_GroupMemberEntity AppendMemberUser(D_GroupMemberEntity member, UserEntity user)
        {
            member.User = user;
            return member;
        }

        /// <summary>
        /// 将经理添加到新组中成为新组员
        /// </summary>
        /// <param name="_context"></param>
        /// <param name="member"></param>
        private static void AddMemberToGroup(NFineDbContext _context, Trigger trigger, D_GroupMemberEntity member)
        {
            //----- ① 找到当前新组员的推荐人
            //获取推荐人和经营组
            var result = GetReferenceUserGroup(_context, trigger, member, member.IsOperator ? 1 : 0);
            //----- ② 将新组员加入到组中并给推荐人业绩+1
            D_GroupMemberEntity newMemberUser = new D_GroupMemberEntity()
            {
                ID = Common.GuId(),
                GroupID = result.Group.ID,  //新组ID
                MemberID = member.MemberID,
                MemberName = member.MemberName,
                OrderID = 99,
                PromotionTime = trigger.Time,
                Amount = 0,
                ManagerCount = member.ManagerCount, //当经理次数
                GroupStatus = 3,
                GroupStatusText = "新组员",
                IsOperator = result.Group.GroupType == 1,
                IsJinsuo = result.IsJinsuo,
                GroupRef = result.GroupMember?.ID
            };
            _context.Set<D_GroupMemberEntity>().Add(newMemberUser);
            //更新晋升人员的CurrentGroupID
            {
                UserEntity jsUser = _context.Set<UserEntity>().FirstOrDefault(a => a.F_Id == newMemberUser.MemberID);
                jsUser.CurrentGroupID = newMemberUser.GroupID;
                _context.Entry<UserEntity>(jsUser).State = System.Data.Entity.EntityState.Modified;
            }
            _context.SaveChanges();

            //----- 给推荐人业绩+1
            if (result.User != null)      //存在推荐人的情况
            {
                UserEntity tjrUser = result.User;
                D_GroupMemberEntity tjr = _context.Set<D_GroupMemberEntity>().FirstOrDefault(a => a.GroupID == tjrUser.CurrentGroupID && a.MemberID == tjrUser.F_Id);
                tjr.Amount++;
                _context.Entry<D_GroupMemberEntity>(tjr).State = System.Data.Entity.EntityState.Modified;
                _context.SaveChanges();
            }

            //----- ③判断是否存在经理（如果不存在则表示空经营组）
            var objManagerMember = _context.Set<D_GroupMemberEntity>()
                .Join(_context.Set<UserEntity>(), gme => gme.MemberID, ue => ue.F_Id, (gme, ue) => new { gme, ue })
                .FirstOrDefault(obj => obj.gme.GroupID == newMemberUser.GroupID && obj.gme.GroupStatus == 0);
            D_GroupMemberEntity managerMember = null;
            if (objManagerMember != null)
                managerMember = AppendMemberUser(objManagerMember.gme, objManagerMember.ue);
            //根据排序原则获取所有新组员
            var memberList = (from a in _context.Set<D_GroupMemberEntity>()
                              where a.GroupID == newMemberUser.GroupID && a.GroupStatus == 3
                              orderby a.Amount descending, a.PromotionTime ascending, a.OrderID ascending
                              select a).ToArray();
            if (managerMember == null) //不存在经理,空经营组
            {
                //----- ③-①判断是否够7人
                if (memberList.Length == 7)    //够7人,填充职位
                {
                    for (int i = 0; i < memberList.Length; i++)
                    {
                        var newMembe = memberList[i];
                        int k = i + 1;
                        newMembe.OrderID = k;
                        //newMembe.Amount = 0;
                        if (k == 1)
                        {
                            newMembe.GroupStatus = 0;
                            newMembe.GroupStatusText = "经理";
                            if (newMembe.IsOperator)
                            {
                                //￥￥￥￥晋升经营组经理￥￥￥￥
                                UpdateSalary(_context, trigger, newMembe.MemberID, SalaryChangeType.TypeValues.晋升经营组经理, nameof(SalaryChangeType.TypeValues.晋升经营组经理));
                            }
                            else
                            {
                                //￥￥￥￥晋升消费组经理￥￥￥￥
                                UpdateSalary(_context, trigger, newMembe.MemberID, SalaryChangeType.TypeValues.晋升消费组经理, nameof(SalaryChangeType.TypeValues.晋升消费组经理));
                            }
                        }
                        else if (k == 2 || k == 3)
                        {
                            newMembe.GroupStatus = 1;
                            newMembe.GroupStatusText = "副经理";
                        }
                        else
                        {
                            newMembe.GroupStatus = 2;
                            newMembe.GroupStatusText = "组员";
                        }
                    }
                    foreach (var item in memberList)
                        _context.Entry<D_GroupMemberEntity>(item).State = System.Data.Entity.EntityState.Modified;
                }
            }
            else    //正常经营组
            {
                if (result.Group.GroupType == 1)    //经营组
                {
                    //￥￥￥￥经营组进入新组员￥￥￥￥
                    UpdateSalary(_context, trigger, managerMember.MemberID, SalaryChangeType.TypeValues.经营组进入新组员, nameof(SalaryChangeType.TypeValues.经营组进入新组员));
                }
                //----- ③-②判断是否够8人
                if (memberList.Length == 8)
                {
                    bool 是否跳出第一轮经营组 = false;
                    //把经理推送至经营组新组员
                    if (!managerMember.IsOperator)  //消费组经理
                    {
                        //￥￥￥￥晋升经营组新组员￥￥￥￥
                        UpdateSalary(_context, trigger, managerMember.MemberID, SalaryChangeType.TypeValues.消费组经理晋升经营组新组员, nameof(SalaryChangeType.TypeValues.消费组经理晋升经营组新组员));
                    }
                    else                            //经营组经理
                    {
                        //￥￥￥￥经营组进入新组员￥￥￥￥
                        UpdateSalary(_context, trigger, managerMember.MemberID, SalaryChangeType.TypeValues.经营组进入第八个新组员, nameof(SalaryChangeType.TypeValues.经营组进入第八个新组员));
                        //￥￥￥￥经营组经理晋升新组员￥￥￥￥
                        UpdateSalary(_context, trigger, managerMember.MemberID, -SalaryChangeType.TypeValues.经营组经理晋升经营组新组员, nameof(SalaryChangeType.TypeValues.经营组经理晋升经营组新组员));
                        if (managerMember.ManagerCount == 0)
                            是否跳出第一轮经营组 = true;
                        //经营组经理次数+1
                        managerMember.ManagerCount++;

                    }
                    //----- ③-②-① 将当前组经理分到下个经营组
                    managerMember.IsOperator = true;    //经营组
                    AddMemberToGroup(_context, trigger, managerMember);
                    //重要业务
                    //晋升身份
                    if (是否跳出第一轮经营组)
                    {
                        //设置身份为 跳出第一轮经营组
                        var managerUser = _context.Set<UserEntity>().FirstOrDefault(u => u.F_Id == managerMember.MemberID);
                        managerUser.CurrentManagerType = (int)ManagerType.跳出第一轮经营组;
                        _context.Entry<UserEntity>(managerUser).State = System.Data.Entity.EntityState.Modified;
                        //晋升身份
                        JinshengGuanli(_context, managerUser);
                    }


                    //----- ③-②-② 将当前组经营组拆分成两个(并停用旧的经营组)
                    //停用旧经营组
                    D_GroupEntity group = result.Group;
                    group.GroupState = 1;
                    group.SplitTime = trigger.Time;
                    group.TriggerSplitUserID = trigger.UserID;
                    _context.Entry<D_GroupEntity>(group).State = System.Data.Entity.EntityState.Modified;
                    //创建两个新组
                    D_GroupEntity group1 = new D_GroupEntity();
                    D_GroupEntity group2 = new D_GroupEntity();
                    group1.ID = Common.GuId();
                    group2.ID = Common.GuId();
                    group1.CreateTime = group2.CreateTime = trigger.Time;
                    group1.GroupState = group2.GroupState = 0;
                    group1.GroupType = group2.GroupType = member.IsOperator ? 1 : 0;    //经营组?消费组
                    group1.OldGroupID = group2.OldGroupID = group.ID;
                    group1.TriggerCreateUserID = group2.TriggerCreateUserID = trigger.UserID;
                    _context.Set<D_GroupEntity>().Add(group1);
                    _context.Set<D_GroupEntity>().Add(group2);

                    _context.SaveChanges();
                    //----- ③-②-③ 给新组分配人
                    //获取除经理外的其他人（副经理，组员，新组员）

                    var updateMemberQuery = from gm1 in _context.Set<D_GroupMemberEntity>()
                                            join gmnull in _context.Set<D_GroupMemberEntity>() on gm1.ID equals gmnull.GroupRef into gmnullr
                                            from gm2 in gmnullr.DefaultIfEmpty()
                                            where gm1.GroupID == newMemberUser.GroupID && gm1.GroupStatus != 0
                                            select new { gm1, gm2 };
                    var lst = updateMemberQuery.ToArray();
                    var oldMemberList = lst.GroupBy(a => a.gm1, a => a.gm2)
                        .OrderByDescending(a => a.Key.Amount)
                        .ThenBy(a => a.Key.OrderID)
                        .ThenBy(a => a.Key.PromotionTime).ToArray();
                    List<D_GroupMemberEntity> newMemberList = new List<D_GroupMemberEntity>(14);
                    //循环分组
                    for (int i = 0; i < oldMemberList.Length; i++)
                    {
                        int k = i + 1;
                        var g_Member = oldMemberList[i];
                        var oldMember = g_Member.Key;
                        //var oldMember = oldMemberList[i];
                        D_GroupMemberEntity newMenber = new D_GroupMemberEntity();
                        newMenber.ID = Common.GuId();
                        newMenber.MemberID = oldMember.MemberID;
                        newMenber.MemberName = oldMember.MemberName;
                        newMenber.ManagerCount = oldMember.ManagerCount;
                        newMenber.PromotionTime = trigger.Time;
                        newMenber.Amount = oldMember.Amount;    //分组业绩不清零,晋升新组员时清零
                        newMenber.IsOperator = group1.GroupType == 1;
                        newMenber.GroupRef = null; //oldMember.GroupRef;
                        newMenber.OldID = oldMember.ID;
                        if (k <= 2)
                        {
                            newMenber.GroupStatus = 0;
                            newMenber.GroupStatusText = "经理";
                            newMenber.OrderID = 1;
                            newMenber.GroupID = i == 0 ? group1.ID : group2.ID;
                            if (newMenber.IsOperator)
                            {
                                //￥￥￥￥晋升经营组经理￥￥￥￥
                                UpdateSalary(_context, trigger, newMenber.MemberID, SalaryChangeType.TypeValues.晋升经营组经理, nameof(SalaryChangeType.TypeValues.晋升经营组经理));
                            }
                            else
                            {
                                //￥￥￥￥晋升消费组经理￥￥￥￥
                                UpdateSalary(_context, trigger, newMenber.MemberID, SalaryChangeType.TypeValues.晋升消费组经理, nameof(SalaryChangeType.TypeValues.晋升消费组经理));
                            }
                        }
                        else if (k >= 3 && k <= 6)
                        {
                            newMenber.GroupStatus = 1;
                            newMenber.GroupStatusText = "副经理";
                            if (k < 5)
                            {
                                newMenber.OrderID = k - 1;
                                newMenber.GroupID = group1.ID;
                            }
                            else
                            {
                                newMenber.OrderID = k - 3;
                                newMenber.GroupID = group2.ID;
                            }
                        }
                        else
                        {
                            newMenber.GroupStatus = 2;
                            newMenber.GroupStatusText = "组员";
                            if (k <= 10)
                            {
                                newMenber.OrderID = k - 3;
                                newMenber.GroupID = group1.ID;
                            }
                            else
                            {
                                newMenber.OrderID = k - 7;
                                newMenber.GroupID = group2.ID;
                            }
                        }

                        _context.Set<D_GroupMemberEntity>().Add(newMenber);
                        //更新用户的当前GroupID
                        var user = _context.Set<UserEntity>().FirstOrDefault(a => a.F_Id == newMenber.MemberID);
                        user.CurrentGroupID = newMenber.GroupID;
                        _context.Entry<UserEntity>(user).State = System.Data.Entity.EntityState.Modified;

                        foreach (var child in g_Member)
                        {
                            if (child != null)
                            {
                                child.GroupRef = newMenber.ID;
                                _context.Entry<D_GroupMemberEntity>(child).State = System.Data.Entity.EntityState.Modified;
                            }
                        }
                    }
                    _context.SaveChanges();
                }
            }
            _context.SaveChanges();
        }

        /// <summary>
        /// 获取推荐人（递归）和经营组（不存在则创建）
        /// </summary>
        /// <param name="_context"></param>
        /// <param name="trigger"></param>
        /// <param name="userId"></param>
        /// <returns></returns>
        private static Domain.ViewModel.ReferenceUserGroupModel GetReferenceUserGroup(NFineDbContext _context, Trigger trigger, D_GroupMemberEntity whereMember,int? cGroupType)
        {
            var query = from u in _context.Set<UserEntity>()
                        join gm in _context.Set<D_GroupMemberEntity>() on new { uid = u.F_Id, gid = u.CurrentGroupID } equals new { uid = gm.MemberID, gid = gm.GroupID }
                        join g in _context.Set<D_GroupEntity>() on new { gid = u.CurrentGroupID, gtp = cGroupType } equals new { gid = g.ID, gtp = g.GroupType } into r
                        from g2 in r.DefaultIfEmpty()
                        where u.F_Id == whereMember.User.ReferenceID
                        select new Domain.ViewModel.ReferenceUserGroupModel { User = u, Group = g2, GroupMember = gm, IsJinsuo = false };
            Domain.ViewModel.ReferenceUserGroupModel result = query.FirstOrDefault();
            if (result == null || (result.User == null && result.Group == null))    //不存在推荐人
            {
                //创建新经营组
                D_GroupEntity group = new D_GroupEntity()
                {
                    ID = Common.GuId(),
                    CreateTime = trigger.Time,
                    GroupState = 0,
                    GroupType = 1,
                    OldGroupID = "",
                    TriggerCreateUserID = trigger.UserID
                };

                _context.Set<D_GroupEntity>().Add(group);
                _context.SaveChanges();
                return new Domain.ViewModel.ReferenceUserGroupModel { Group = group, User = default(UserEntity), IsJinsuo = false };
            }
            else if (result.User != null && result.Group == null) //推荐人没有进经营组的，找到推荐人的推荐人
            {
                result.GroupMember.User = result.User;
                var r = GetReferenceUserGroup(_context, trigger, result.GroupMember, 1);
                r.IsJinsuo = true;
                return r;
            }
            else  //找到人和组
            {
                //经营组
                if (result.GroupMember.IsOperator)
                {
                    string mid = result.GroupMember.ID;
                    //因为业绩关系有可能在盘外(分盘造成的)，所以不进行GroupID 的判断
                    var lstGme = _context.Set<D_GroupMemberEntity>().Where(gm => gm.GroupRef == mid).ToList();
                    if (lstGme.Count == 2 || (lstGme.Count == 1 && result.GroupMember.ManagerCount > 0 && lstGme[0].IsJinsuo)) //满足两个或（超过第一轮已经且已经有一个紧缩）
                    {
                        result.GroupMember.User = result.User;
                        var r = GetReferenceUserGroup(_context, trigger, result.GroupMember, 1);
                        r.IsJinsuo = true;
                        return r;
                    }
                }
                return result;
            }
        }

        /// <summary>
        /// 更新薪酬，并记录历史,写入公司支出表
        /// </summary>
        private static void UpdateSalary(NFineDbContext _context, Trigger trigger, string userid, decimal amount, string ChangeType)
        {
            var objUser = _context.Set<D_SalaryEntity>()
                .Join(_context.Set<UserEntity>(), s => s.ID, u => u.F_Id, (Salary, User) => new { User, Salary })
                .FirstOrDefault(obj => obj.User.F_Id == userid);

            {
                var history = new D_SalaryHistoryEntity(Common.GuId(), userid, ChangeType, amount, trigger, D_SalaryAccountType.Amount);
                var account = new D_AccountEntity(Common.GuId(), userid, ChangeType, -amount, trigger, D_SalaryAccountType.Amount, history.ID, false);
                _context.Set<D_SalaryHistoryEntity>().Add(history); //新增薪酬历史
                _context.Set<D_AccountEntity>().Add(account);       //新增支出记录
            }
            objUser.Salary.Amount += amount;
            _context.Entry<D_SalaryEntity>(objUser.Salary).State = System.Data.Entity.EntityState.Modified; //更新值
            _context.SaveChanges();
        }

        /// <summary>
        /// 孵化基金比例
        /// </summary>
        private static decimal getFuhuaBili(int? currentManagerType)
        {
            decimal bili = 0.01M;
            switch (currentManagerType)
            {
                case (int)ManagerType.黄金董事:
                    bili = 0.06M;
                    break;
                case (int)ManagerType.红宝石董事:
                    bili = 0.07M;
                    break;
                case (int)ManagerType.翡翠董事:
                    bili = 0.08M;
                    break;
                case (int)ManagerType.钻石董事:
                    bili = 0.09M;
                    break;
                case (int)ManagerType.荣誉董事:
                    bili = 0.10M;
                    break;
            }
            return bili;
        }

        /// <summary>
        /// 管理奖收入比例
        /// </summary>
        private static decimal geGuanliBili(int? currentManagerType)
        {
            decimal bili = 0.01M;
            switch (currentManagerType)
            {
                case (int)ManagerType.黄金董事:
                    bili = 0.01M;
                    break;
                case (int)ManagerType.红宝石董事:
                    bili = 0.02M;
                    break;
                case (int)ManagerType.翡翠董事:
                    bili = 0.03M;
                    break;
                case (int)ManagerType.钻石董事:
                    bili = 0.04M;
                    break;
                case (int)ManagerType.荣誉董事:
                    bili = 0.01M;
                    break;
            }
            return bili;
        }

        /// <summary>
        ///1,计算管理奖;2,增加点位数;3,计算福利奖(车奖、房奖)
        /// </summary>
        private static void BonusAndAddPoints(NFineDbContext _context, Trigger trigger, string referenceID)
        {
            decimal jicha = 0;
            var cUser = _context.Set<UserEntity>().FirstOrDefault(cu => cu.F_Id == referenceID);
            while (cUser != null)
            {
                var dse = _context.Set<D_SalaryEntity>().FirstOrDefault(s => s.ID == cUser.F_Id);
                /*-------第一步、计算管理奖------------*/
                if (cUser.CurrentManagerType >= (int)ManagerType.黄金董事)
                {
                    decimal fuhuabili = getFuhuaBili(cUser.CurrentManagerType);
                    decimal guanlibili = geGuanliBili(cUser.CurrentManagerType);
                    decimal 应收 = SalaryChangeType.TypeValues.公司进入一个点位 * (guanlibili - jicha);   //极差计算
                    jicha = guanlibili;
                    decimal 税收 = decimal.Round(应收 * 0.05M, 2);
                    decimal 实际收入 = 应收 - 税收;
                    decimal 孵化基金 = decimal.Round(实际收入 * fuhuabili, 2);
                    decimal 入账值 = 实际收入 - 孵化基金;
                    //①个人收入入账记录
                    //公司出账记录
                    {
                        var history = new D_SalaryHistoryEntity(Common.GuId(), cUser.F_Id, SalaryChangeType.TypeValues.管理奖收入, 应收, trigger, D_SalaryAccountType.Amount);
                        var account = new D_AccountEntity(Common.GuId(), cUser.F_Id, SalaryChangeType.TypeValues.管理奖收入, -应收, trigger, D_SalaryAccountType.Amount, history.ID, false);
                        _context.Set<D_SalaryHistoryEntity>().Add(history); //新增薪酬历史
                        _context.SaveChanges();
                        _context.Set<D_AccountEntity>().Add(account);       //新增支出记录
                        _context.SaveChanges();
                    }
                    //②个人扣税入账记录
                    //公司收税入账记录
                    {
                        var history = new D_SalaryHistoryEntity(Common.GuId(), cUser.F_Id, SalaryChangeType.TypeValues.个人所得税, -税收, trigger, D_SalaryAccountType.Amount);
                        var account = new D_AccountEntity(Common.GuId(), cUser.F_Id, SalaryChangeType.TypeValues.个人所得税, 税收, trigger, D_SalaryAccountType.Amount, history.ID, true);
                        _context.Set<D_SalaryHistoryEntity>().Add(history); //新增薪酬历史
                        _context.SaveChanges();
                        _context.Set<D_AccountEntity>().Add(account);       //新增支出记录
                        _context.SaveChanges();
                    }
                    //③个人账户出账记录
                    //个人孵化基金入账记录
                    {
                        var history = new D_SalaryHistoryEntity(Common.GuId(), cUser.F_Id, SalaryChangeType.TypeValues.个人孵化基金, -孵化基金, trigger, D_SalaryAccountType.Amount);
                        var history2 = new D_SalaryHistoryEntity(Common.GuId(), cUser.F_Id, SalaryChangeType.TypeValues.个人孵化基金, 孵化基金, trigger, D_SalaryAccountType.HatchAmount);
                        _context.Set<D_SalaryHistoryEntity>().Add(history); //新增薪酬历史
                        _context.SaveChanges();
                        _context.Set<D_SalaryHistoryEntity>().Add(history2);//新增支出记录
                        _context.SaveChanges();
                    }
                    //④公司孵化基金配资入账记录
                    //公司孵化基金配资出账记录
                    {
                        var history = new D_SalaryHistoryEntity(Common.GuId(), cUser.F_Id, SalaryChangeType.TypeValues.公司孵化基金, 孵化基金, trigger, D_SalaryAccountType.GiveAmount);
                        var account = new D_AccountEntity(Common.GuId(), cUser.F_Id, SalaryChangeType.TypeValues.公司孵化基金, -孵化基金, trigger, D_SalaryAccountType.GiveAmount, history.ID, false);
                        _context.Set<D_SalaryHistoryEntity>().Add(history); //新增薪酬历史
                        _context.SaveChanges();
                        _context.Set<D_AccountEntity>().Add(account);       //新增支出记录
                        _context.SaveChanges();
                    }
                    dse.Amount += 入账值;
                    dse.HatchAmount += 孵化基金;
                    dse.GiveAmount += 孵化基金;
                }
                /*-------第二步、增加点位数------------*/
                cUser.CumulativePoints++;
                _context.Entry<UserEntity>(cUser).State = System.Data.Entity.EntityState.Modified;
                _context.SaveChanges();

                /*-------第三步、计算福利奖------------*/

                //小区点位数
                var minPoints = _context.Set<UserEntity>().Where(u => u.ReferenceID == cUser.F_Id).Min(u => u.CumulativePoints + 1);

                var cumulativeAmount = minPoints * SalaryChangeType.TypeValues.公司进入一个点位;
                if (cumulativeAmount >= SalaryChangeType.TypeValues.福利房累计 && cUser.WelfarePrize < 2)     //房奖励：大于等于4000万且未拿过房奖励的
                {
                    var history = new D_SalaryHistoryEntity(Common.GuId(), cUser.F_Id, nameof(SalaryChangeType.TypeValues.福利房奖励), SalaryChangeType.TypeValues.福利房奖励, trigger, D_SalaryAccountType.Amount);
                    var account = new D_AccountEntity(Common.GuId(), cUser.F_Id, nameof(SalaryChangeType.TypeValues.福利房奖励), -SalaryChangeType.TypeValues.福利房奖励, trigger, D_SalaryAccountType.Amount, history.ID, false);
                    _context.Set<D_SalaryHistoryEntity>().Add(history); //新增薪酬历史
                    _context.SaveChanges();
                    _context.Set<D_AccountEntity>().Add(account);       //新增支出记录
                    dse.Amount += SalaryChangeType.TypeValues.福利房奖励;
                    _context.SaveChanges();
                }
                else if (cumulativeAmount >= SalaryChangeType.TypeValues.福利车累计 && cUser.WelfarePrize < 1)//车奖励：大于等于2000万且未拿过车奖励的
                {
                    var history = new D_SalaryHistoryEntity(Common.GuId(), cUser.F_Id, nameof(SalaryChangeType.TypeValues.福利车奖励), SalaryChangeType.TypeValues.福利车奖励, trigger, D_SalaryAccountType.Amount);
                    var account = new D_AccountEntity(Common.GuId(), cUser.F_Id, nameof(SalaryChangeType.TypeValues.福利车奖励), -SalaryChangeType.TypeValues.福利车奖励, trigger, D_SalaryAccountType.Amount, history.ID, false);
                    _context.Set<D_SalaryHistoryEntity>().Add(history); //新增薪酬历史
                    _context.SaveChanges();
                    _context.Set<D_AccountEntity>().Add(account);       //新增支出记录
                    dse.Amount += SalaryChangeType.TypeValues.福利车奖励;
                    _context.SaveChanges();
                }
                _context.Entry<D_SalaryEntity>(dse).State = System.Data.Entity.EntityState.Modified; //更新值
                _context.SaveChanges();

                //继续递归
                cUser = _context.Set<UserEntity>().FirstOrDefault(cu => cu.F_Id == cUser.ReferenceID);
            }
        }

        /// <summary>
        /// 代理将计算（根据地址计算）
        /// </summary>
        private static void AreaProxy(NFineDbContext _context, Trigger trigger, UserEntity regUser)
        {
            string[] codes = new string[] { regUser.F_Province, regUser.F_City, regUser.F_Area };

            var proxys = _context.Set<UserEntity>()
                .Join(_context.Set<D_SalaryEntity>(), s => s.F_Id, u => u.ID, (User, Salary) => new { User, Salary })
            .Where(obj => obj.User.ProxyType != 0 && codes.Contains(obj.User.ProxyCode) && obj.User.F_Id != regUser.F_Id);

            foreach (var item in proxys)
            {
                decimal bili = 0;
                string ctype = "";
                switch (item.User.ProxyType)
                {
                    case 1:
                        bili = 0.01M;
                        ctype = SalaryChangeType.TypeValues.省代理分成;
                        break;
                    case 2:
                        bili = 0.02M;
                        ctype = SalaryChangeType.TypeValues.市代理分成;
                        break;
                    case 3:
                        bili = 0.03M;
                        ctype = SalaryChangeType.TypeValues.区县代理分成;
                        break;
                }
                decimal val = decimal.Round(SalaryChangeType.TypeValues.公司进入一个点位 * bili, 2);
                item.Salary.Amount += val;
                _context.Entry<D_SalaryEntity>(item.Salary).State = System.Data.Entity.EntityState.Modified;

                var history = new D_SalaryHistoryEntity(Common.GuId(), item.User.F_Id, ctype, val, trigger, D_SalaryAccountType.Amount);
                var account = new D_AccountEntity(Common.GuId(), item.User.F_Id, ctype, -val, trigger, D_SalaryAccountType.Amount, history.ID, false);
                _context.Set<D_SalaryHistoryEntity>().Add(history); //新增薪酬历史
                _context.Set<D_AccountEntity>().Add(account);       //新增支出记录
            }
            _context.SaveChanges();
        }

        #region 管理奖辅助方法

        /// <summary>
        /// 获取人
        /// </summary>
        private static UserEntity AppendUserAmount(UserEntity user, D_SalaryEntity sal)
        {
            user.D_Amount = sal.Amount;
            user.D_RepeatAmount = sal.RepeatAmount;
            user.D_HatchAmount = sal.HatchAmount;
            user.D_GiveAmount = sal.GiveAmount;
            return user;
        }

        /// <summary>
        /// 找上级推荐人
        /// </summary>
        private static UserEntity GetReferenceManager(NFineDbContext _context, string referenceID)
        {
            var cUser = _context.Set<UserEntity>()
                .FirstOrDefault(user => user.F_Id == referenceID);
            return cUser;
        }

        #endregion

        /// <summary>
        /// 晋升不同级别的条件
        /// </summary>
        private static ManagerType[] Get晋升条件(ManagerType tp)
        {
            //左小右大的原则写
            ManagerType[] tj = null;
            switch (tp)
            {
                case ManagerType.跳出第一轮经营组:
                    break;
                case ManagerType.黄金董事:
                    tj = new ManagerType[] { ManagerType.跳出第一轮经营组, ManagerType.跳出第一轮经营组 };
                    break;
                case ManagerType.红宝石董事:
                    tj = new ManagerType[] { ManagerType.跳出第一轮经营组, ManagerType.黄金董事 };
                    break;
                case ManagerType.翡翠董事:
                    tj = new ManagerType[] { ManagerType.跳出第一轮经营组, ManagerType.红宝石董事 };
                    break;
                case ManagerType.钻石董事:
                    tj = new ManagerType[] { ManagerType.跳出第一轮经营组, ManagerType.翡翠董事 };
                    break;
                case ManagerType.荣誉董事:
                    tj = new ManagerType[] { ManagerType.钻石董事, ManagerType.钻石董事 };
                    break;
            }
            return tj;
        }

        /// <summary>
        /// 晋升到管理员
        /// </summary>
        /// <param name="_context"></param>
        /// <param name="leftUser"></param>
        private static void JinshengGuanli(NFineDbContext _context, UserEntity leftUser)
        {
            ManagerType maxLeftType = (ManagerType)leftUser.CurrentManagerType;
            UserEntity topUser = GetReferenceManager(_context, leftUser.ReferenceID);
            while (topUser != null)
            {
                var updateManagerType = ManagerType.黄金董事;
                bool 需要晋升 = true;
                while (topUser.CurrentManagerType >= (int)updateManagerType) //topUser大于等于要晋升的位置
                {
                    if (updateManagerType == ManagerType.荣誉董事)  //荣誉董事不再变更身份
                    {
                        需要晋升 = false;
                        break;
                    }
                    updateManagerType = (ManagerType)(updateManagerType + 1);
                }
                //晋升
                if (需要晋升 && topUser.CurrentManagerType == ((int)updateManagerType - 1))
                {
                    bool 是否判断右区 = true;
                    var tiaojian = Get晋升条件(updateManagerType);
                    ManagerType leftType = default(ManagerType);
                    if (maxLeftType >= tiaojian[1])
                        leftType = tiaojian[0];
                    else if (maxLeftType >= tiaojian[0] && maxLeftType < tiaojian[1])
                        leftType = tiaojian[1];
                    else
                        是否判断右区 = false;
                    if (是否判断右区)
                    {
                        //获取右区情况
                        List<string> pIDs = new List<string>();
                        pIDs.Add(topUser.F_Id);
                        bool hasChildren = false;
                        do
                        {
                            //获取右区子节点
                            var children = _context.Set<UserEntity>()
                                .Where(user => pIDs.Contains(user.ReferenceID) && user.F_Id != leftUser.F_Id).ToList();
                            pIDs.Clear();
                            hasChildren = false;
                            foreach (var rightUser in children)
                            {
                                hasChildren = true;
                                //符合右区条件
                                if (rightUser.CurrentManagerType >= (int)leftType)
                                {
                                    //晋升topUser
                                    topUser.CurrentManagerType = (int)updateManagerType;
                                    topUser.CurrentManager = updateManagerType.ToString();
                                    _context.Entry<UserEntity>(topUser).State = System.Data.Entity.EntityState.Modified;
                                    _context.SaveChanges();
                                    break;
                                }
                                //不符合继续

                                pIDs.Add(rightUser.F_Id);
                            }
                        } while (hasChildren);
                    }
                }
                //计算左区最大等级
                if ((ManagerType)topUser.CurrentManagerType > maxLeftType)
                    maxLeftType = (ManagerType)topUser.CurrentManagerType;
                //递推上级
                leftUser = topUser;
                topUser = GetReferenceManager(_context, leftUser.ReferenceID);
            }
        }

        /// <summary>
        /// 复投账户计算
        /// </summary>
        /// <param name="_context"></param>
        /// <param name="trigger"></param>
        /// <param name="regUser"></param>
        private static void RepeatAmount(NFineDbContext _context, Trigger trigger, UserEntity regUser)
        {
            string[] changeTypes = new string[] 
            {
                nameof(SalaryChangeType.TypeValues.晋升消费组经理),
                nameof(SalaryChangeType.TypeValues.消费组经理晋升经营组新组员),
                nameof(SalaryChangeType.TypeValues.经营组经理晋升经营组新组员),
                nameof(SalaryChangeType.TypeValues.晋升经营组经理),
                nameof(SalaryChangeType.TypeValues.经营组进入新组员),
                nameof(SalaryChangeType.TypeValues.经营组进入第八个新组员)
            };
            var topuser = _context.Set<UserEntity>().FirstOrDefault(u => u.F_Id == regUser.ReferenceID);
            string idcardNow = "";
            while (topuser != null)
            {
                if (!topuser.IsRepeat.SafeValue() && topuser.F_CardId != idcardNow)      //未复投过,且不是自己
                {
                    //获取当前身份证的第一个点位
                    var firstUser = _context.Set<UserEntity>()
                        .Where(u => u.F_CardId == topuser.F_CardId)
                        .OrderBy(u => u.F_CreatorTime).FirstOrDefault();
                    idcardNow = firstUser.F_CardId;
                    if (!firstUser.IsRepeat.SafeValue()) //第一个点位未复投过
                    {
                        var userCount = _context.Set<UserEntity>().Count(u => u.F_CardId == idcardNow);
                        if (userCount >= 7)
                        {
                            //获取点位的当前点位的总收入
                            var sumAmount = _context.Set<UserEntity>()
                                .Join(_context.Set<D_SalaryHistoryEntity>(), u => u.F_Id, sh => sh.UserID, (User, SalaryHistory) => new { User, SalaryHistory })
                                .Where(obj => obj.User.F_CardId == idcardNow && obj.SalaryHistory.AccountType == (int)D_SalaryAccountType.Amount && changeTypes.Contains(obj.SalaryHistory.ChangeType))
                                .GroupBy(obj => obj.User.F_CardId)
                                .Select(gp => gp.Sum(obj => obj.SalaryHistory.ChangeAmount))
                                .FirstOrDefault();

                            //大于21万就执行复投
                            if (sumAmount > SalaryChangeType.TypeValues.进入复投累计金额)
                            {
                                var objUser = _context.Set<UserEntity>()
                                 .Join(_context.Set<D_SalaryEntity>(), u => u.F_Id, s => s.ID, (User, Salary) => new { User, Salary })
                                 .Where(obj => obj.User.F_CardId == idcardNow)
                                 .OrderBy(obj => obj.User.F_CreatorTime)
                                 .FirstOrDefault();
                                if (objUser != null)
                                {
                                    decimal val = SalaryChangeType.TypeValues.公司进入一个点位 * 8;
                                    objUser.Salary.Amount -= val;
                                    objUser.Salary.RepeatAmount += val;
                                    //个人账户出账记录
                                    //复投账户入账记录
                                    {
                                        var history = new D_SalaryHistoryEntity(Common.GuId(), objUser.User.F_Id, SalaryChangeType.TypeValues.进入复投账户, -val, trigger, D_SalaryAccountType.Amount);
                                        var history2 = new D_SalaryHistoryEntity(Common.GuId(), objUser.User.F_Id, SalaryChangeType.TypeValues.进入复投账户, val, trigger, D_SalaryAccountType.RepeatAmount);
                                        _context.Set<D_SalaryHistoryEntity>().Add(history); //新增薪酬历史
                                        _context.SaveChanges();
                                        _context.Set<D_SalaryHistoryEntity>().Add(history2);//新增入账记录
                                        _context.SaveChanges();
                                    }
                                    _context.Entry<D_SalaryEntity>(objUser.Salary).State = System.Data.Entity.EntityState.Modified;
                                    _context.SaveChanges();
                                }
                            }

                        }
                    }
                }
                //递归上级查询
                topuser = _context.Set<UserEntity>().FirstOrDefault(u => u.F_Id == topuser.ReferenceID);
            }

        }

        #endregion

        #region 初始化第一个会员账户

        public void RegisterFirstUser(UserEntity registUser, UserLogOnEntity userLogOnEntity, string GoodIds)
        {
            var Nums = GoodIds.Split(',');
            if (Nums.Length != 1)
                throw new Exception("只能选择一个商品");
            using (var scope = new TransactionScope(TransactionScopeOption.Required, new TransactionOptions { IsolationLevel = IsolationLevel.ReadUncommitted }))
            {
                registUser.F_Id = Common.GuId();
                registUser.F_EnabledMark = true;
                registUser.F_IsAdministrator = false;
                registUser.F_MemberMoney = 0;
                registUser.ReferenceID = null;  //初始化起盘代码,设为null
                registUser.CurrentManagerType = 0;
                registUser.CumulativePoints = 0;

                userLogOnEntity.F_Id = registUser.F_Id;
                userLogOnEntity.F_UserId = registUser.F_Id;
                userLogOnEntity.F_UserSecretkey = Md5.md5(Common.CreateNo(), 16).ToLower();
                userLogOnEntity.F_UserPassword = Md5.md5(DESEncrypt.Encrypt(Md5.md5(userLogOnEntity.F_UserPassword, 32).ToLower(), userLogOnEntity.F_UserSecretkey).ToLower(), 32).ToLower();

                var _context = new RepositoryBase().Dbcontext;
                var rUser = _context.Set<UserEntity>().FirstOrDefault(u => string.IsNullOrEmpty(u.ReferenceID) && u.F_IsAdministrator == false);
                if (rUser != null)
                    throw new Exception("已经存在起盘账户，不能再注册");
                Trigger trigger = new Trigger()
                {
                    Time = registUser.F_CreatorTime.Value,
                    UserID = registUser.F_Id
                };

                //创建一个消费组
                D_GroupEntity group = new D_GroupEntity()
                {
                    ID = Common.GuId(),
                    CreateTime = trigger.Time,
                    GroupState = 0,
                    GroupType = 0,      //消费组
                    OldGroupID = "",
                    TriggerCreateUserID = trigger.UserID
                };
                registUser.CurrentGroupID = group.ID;
                registUser.RCount = 0;
                //增加薪金表
                var salary = new D_SalaryEntity(registUser.F_Id);
                //新增组员
                D_GroupMemberEntity newMemberUser = new D_GroupMemberEntity()
                {
                    ID = Common.GuId(),
                    GroupID = registUser.CurrentGroupID,
                    MemberID = registUser.F_Id,
                    MemberName = registUser.F_Account,
                    OrderID = 99,
                    PromotionTime = registUser.F_CreatorTime,
                    Amount = 0,
                    ManagerCount = 0,
                    GroupStatus = 3,
                    GroupStatusText = "新组员",
                    IsOperator = false,
                    IsJinsuo = false
                };
                {
                    var account = new D_AccountEntity();
                    account.ID = Common.GuId();
                    account.ChangeAmount = SalaryChangeType.TypeValues.公司进入一个点位;
                    account.ChangeType = nameof(SalaryChangeType.TypeValues.公司进入一个点位);
                    account.TriggerTime = trigger.Time;
                    account.TriggerUserID = trigger.UserID;
                    account.UserID = trigger.UserID;
                    account.BussID = "";    //业务ID
                    account.IsIncome = true;
                    _context.Set<D_AccountEntity>().Add(account);       //新增支出记录
                }
                decimal allMoney = 0;
                /* 订单相关的代码 */
                foreach (var id in GoodIds.Split(','))
                {
                    D_GoodsEntity goodsEntity = _context.Set<D_GoodsEntity>().FirstOrDefault(g => g.F_Id == id);
                    if (goodsEntity == null)
                        throw new Exception("未选择商品！");
                    D_IndentEntity indentEntity = new D_IndentEntity();
                    indentEntity.Create();
                    indentEntity.D_M_F_ID = registUser.F_Id;
                    indentEntity.D_G_F_ID = id;
                    indentEntity.F_Nums = 1;
                    indentEntity.F_OrderDate = System.DateTime.Now;
                    indentEntity.F_OrderType = "0";
                    indentEntity.F_MemName = registUser.F_RealName;
                    indentEntity.F_MemAccount = registUser.F_AccountName;
                    indentEntity.F_MemTel = registUser.F_MobilePhone;
                    indentEntity.F_OrderAddress = registUser.F_Address;
                    indentEntity.F_CreatorTime = indentEntity.F_OrderDate;
                    indentEntity.F_CreatorUserId = registUser.ReferenceID;
                    indentEntity.F_EnabledMark = false;
                    indentEntity.F_Name = goodsEntity.F_Name;
                    indentEntity.F_Price = goodsEntity.F_Price;
                    indentEntity.F_Inte = goodsEntity.F_Inte;
                    indentEntity.F_Spec = goodsEntity.F_Spec;
                    indentEntity.F_Summary = goodsEntity.F_Summary;
                    allMoney = allMoney + goodsEntity.F_Price.SafeValue();
                    _context.Set<D_IndentEntity>().Add(indentEntity);
                }

                /* 订单代码结束 */

                _context.Set<D_GroupMemberEntity>().Add(newMemberUser);
                _context.Set<D_GroupEntity>().Add(group);
                _context.Set<D_SalaryEntity>().Add(salary);
                _context.Set<UserEntity>().Add(registUser);
                _context.Set<UserLogOnEntity>().Add(userLogOnEntity);
                _context.SaveChanges();
                scope.Complete();
            }
        }

        #endregion

        #region 查询

        public List<D_SalaryHistoryEntity> GetUserSalary(string userId)
        {
            using (var db = new RepositoryBase())
            {
                var query = from sh in db.DbSet<D_SalaryHistoryEntity>()
                            join u1 in db.DbSet<UserEntity>() on sh.UserID equals u1.F_Id
                            join u2 in db.DbSet<UserEntity>() on sh.TriggerUserID equals u2.F_Id
                            where sh.UserID == userId
                            select new { sh, u1, u2 };

                List<D_SalaryHistoryEntity> lst = new List<D_SalaryHistoryEntity>();
                foreach (var obj in query)
                {
                    obj.sh.Account = obj.u1.F_Account;
                    obj.sh.AccountName = obj.u1.F_AccountName;
                    obj.sh.TAccount = obj.u2.F_Account;
                    obj.sh.TAccountName = obj.u2.F_AccountName;
                    lst.Add(obj.sh);
                }
                return lst;
            }
        }

        public List<D_AccountEntity> GetCompanyAccount()
        {
            using (var db = new RepositoryBase())
            {
                var query = from sh in db.DbSet<D_AccountEntity>()
                            join u1 in db.DbSet<UserEntity>() on sh.UserID equals u1.F_Id
                            join u2 in db.DbSet<UserEntity>() on sh.TriggerUserID equals u2.F_Id
                            //where sh.UserID == userId
                            orderby sh.TriggerTime descending
                            select new { sh, u1, u2 };

                List<D_AccountEntity> lst = new List<D_AccountEntity>();
                foreach (var obj in query)
                {
                    obj.sh.Account = obj.u1.F_Account;
                    obj.sh.AccountName = obj.u1.F_AccountName;
                    obj.sh.TAccount = obj.u2.F_Account;
                    obj.sh.TAccountName = obj.u2.F_AccountName;
                    lst.Add(obj.sh);
                }
                return lst;
            }
        }

        public List<D_AccountEntity> GetCompanyAccount(Expression<Func<D_AccountEntity, bool>> predicate, Expression<Func<UserEntity, bool>> predicate1, Pagination pagination)
        {
            using (var db = new RepositoryBase())
            {
                var baselinq = from sh in db.DbSet<D_AccountEntity>().Where(predicate)
                                join u1 in db.DbSet<UserEntity>().Where(predicate1) on sh.UserID equals u1.F_Id
                                join u2 in db.DbSet<UserEntity>() on sh.TriggerUserID equals u2.F_Id
                                orderby sh.TriggerTime descending
                                select new { sh, u1, u2 };
                //baselinq.
                //var basel = baselinq.Provider.CreateQuery(predicate);
                pagination.records = baselinq.Count();
                
                var query = baselinq.Skip(pagination.rows * (pagination.page - 1)).Take(pagination.rows).AsQueryable();

                List<D_AccountEntity> lst = new List<D_AccountEntity>();
                foreach (var obj in query)
                {
                    obj.sh.Account = obj.u1.F_Account;
                    obj.sh.AccountName = obj.u1.F_RealName;
                    obj.sh.TAccount = obj.u2.F_Account;
                    obj.sh.TAccountName = obj.u2.F_RealName;
                    lst.Add(obj.sh);
                }
                return lst;
            }
        }
        public List<D_AccountEntity> GetCompanyAccount(Expression<Func<D_AccountEntity, bool>> predicate, Expression<Func<UserEntity, bool>> predicate1)
        {
            using (var db = new RepositoryBase())
            {
                var baselinq = from sh in db.DbSet<D_AccountEntity>().Where(predicate)
                                join u1 in db.DbSet<UserEntity>().Where(predicate1) on sh.UserID equals u1.F_Id
                                join u2 in db.DbSet<UserEntity>() on sh.TriggerUserID equals u2.F_Id
                                orderby sh.TriggerTime descending
                                select new { sh, u1, u2 };

                List<D_AccountEntity> lst = new List<D_AccountEntity>();
                foreach (var obj in baselinq)
                {
                    obj.sh.Account = obj.u1.F_Account;
                    obj.sh.AccountName = obj.u1.F_AccountName;
                    obj.sh.TAccount = obj.u2.F_Account;
                    obj.sh.TAccountName = obj.u2.F_AccountName;
                    lst.Add(obj.sh);
                }
                return lst;
            }
        }

        public List<D_SalaryHistoryEntity> GetUserSalary(string userId, Expression predicate, Pagination pagination)
        {
            using (var db = new RepositoryBase())
            {
                var baselinq = (from sh in db.DbSet<D_SalaryHistoryEntity>()
                                join u1 in db.DbSet<UserEntity>() on sh.UserID equals u1.F_Id
                                join u2 in db.DbSet<UserEntity>() on sh.TriggerUserID equals u2.F_Id
                                where sh.UserID == userId
                                select new { sh, u1, u2 }).OrderByDescending(p => p.sh.TriggerTime).ThenByDescending(p => p.sh.ID);
                pagination.records = baselinq.Count();
                var query = baselinq.Skip(pagination.rows * (pagination.page - 1)).Take(pagination.rows).AsQueryable();

                List<D_SalaryHistoryEntity> lst = new List<D_SalaryHistoryEntity>();
                foreach (var obj in query)
                {
                    obj.sh.Account = obj.u1.F_Account;
                    obj.sh.AccountName = obj.u1.F_RealName;
                    obj.sh.TAccount = obj.u2.F_Account;
                    obj.sh.TAccountName = obj.u2.F_RealName;
                    lst.Add(obj.sh);
                }
                return lst;
            }
        }

        public List<UserEntity> GetMembersList(Expression<Func<UserEntity, bool>> expression, Pagination pagination)
        {
            using (var db = new RepositoryBase())
            {
                var baselinq = from my in db.DbSet<UserEntity>().Where(expression)
                                join sal in db.DbSet<D_SalaryEntity>() on my.F_Id equals sal.ID
                                join u2 in db.DbSet<UserEntity>() on my.ReferenceID equals u2.F_Id into r1
                                from refu in r1.DefaultIfEmpty()
                                where my.F_IsAdministrator == false
                                orderby my.F_CreatorTime descending
                                select new { my, refu, sal };
                pagination.records = baselinq.Count();
                var query = baselinq.Skip(pagination.rows * (pagination.page - 1)).Take(pagination.rows).AsQueryable();

                List<UserEntity> lst = new List<UserEntity>();
                foreach (var obj in query)
                {
                    obj.my.F_MemberMoney = obj.sal.Amount;
                    obj.my.ReferenceAccount = obj.refu?.F_Account;
                    obj.my.ReferenceName = obj.refu?.F_RealName;
                    lst.Add(obj.my);
                }
                return lst;
            }
        }

        public List<UserEntity> GetMembersList(Expression<Func<UserEntity, bool>> expression)
        {
            using (var db = new RepositoryBase())
            {
                var baselinq = from my in db.DbSet<UserEntity>().Where(expression)
                               join sal in db.DbSet<D_SalaryEntity>() on my.F_Id equals sal.ID
                               join u2 in db.DbSet<UserEntity>() on my.ReferenceID equals u2.F_Id into r1
                               from refu in r1.DefaultIfEmpty()
                               where my.F_IsAdministrator == false
                               orderby my.F_CreatorTime descending
                               select new { my, refu, sal };

                List<UserEntity> lst = new List<UserEntity>();
                foreach (var obj in baselinq)
                {
                    obj.my.F_MemberMoney = obj.sal.Amount;
                    obj.my.ReferenceAccount = obj.refu?.F_Account;
                    obj.my.ReferenceName = obj.refu?.F_RealName;
                    lst.Add(obj.my);
                }
                return lst;
            }
        }

        private List<UserEntity> GetAreasById(string userId, NFineDbContext db)
        {
            List<UserEntity> lst = db.Set<UserEntity>()
                .Where(u => u.ReferenceID == userId)
                .OrderBy(u=>u.F_CreatorTime)
                .ToList();
            foreach (var obj in lst)
            {
                var  models = GetAreasById(obj.F_Id, db);
                if (obj.childrens == null)
                    obj.childrens = new List<UserEntity>();
                obj.childrens.AddRange(models);
            }
            return lst;
        }

        public UserEntity GetAreas(string userId)
        {
            using (var db = new RepositoryBase().Dbcontext)
            {
                UserEntity entity = db.Set<UserEntity>().FirstOrDefault(p=>p.F_Id==userId);
                List<UserEntity> models = GetAreasById(userId, db);
                if (entity.childrens == null)
                    entity.childrens = new List<UserEntity>();
                entity.childrens.AddRange(models);
                return entity;
            }
        }

        public UserEntity GetForm(string userId)
        {
            using (var db = new RepositoryBase())
            {
                if (!OperatorProvider.Provider.GetCurrent().IsMember)
                {
                    var obj = (from m in db.DbSet<UserEntity>()
                               join n in db.DbSet<UserEntity>() on m.ReferenceID equals n.F_Id into right
                               from t in right.DefaultIfEmpty()
                               where m.F_Id == userId
                               select new { m, t }).FirstOrDefault();
                    if (obj == null)
                        return null;
                    UserEntity entity = obj.m;
                    entity.ReferenceAccount = obj.t?.F_Account;
                    entity.ReferenceName = obj.t?.F_RealName;
                    return entity;
                }
                else
                {
                    var obj = (from m in db.DbSet<UserEntity>()
                               join sal in db.DbSet<D_SalaryEntity>() on m.F_Id equals sal.ID
                               join n in db.DbSet<UserEntity>() on m.ReferenceID equals n.F_Id into right
                               from t in right.DefaultIfEmpty()
                               where m.F_Id == userId
                               select new { m, t, sal }).FirstOrDefault();
                    if (obj == null)
                        return null;
                    UserEntity entity = obj.m;
                    entity.ReferenceAccount = obj.t?.F_Account;
                    entity.ReferenceName = obj.t?.F_RealName;
                    entity.F_MemberMoney = obj.sal?.Amount;
                    return entity;
                }
                
            }
        }

        public D_SalaryEntity GetAmcount(string userId)
        {
            using (var db = new RepositoryBase())
            {
                var list = from m in db.DbSet<D_SalaryEntity>()
                           where m.ID == userId
                           select new { m };

                D_SalaryEntity entity = new D_SalaryEntity();
                foreach (var obj in list)
                {
                    entity = obj.m;
                }
                return entity;
            }
        }

        public UserEntity GetAllMemberFormJson(string keyValue)
        {
            using (var db = new RepositoryBase())
            {
                var list = db.FindList<UserEntity>(@"select a.F_Account,a.F_RealName,a.F_MobilePhone,a.F_CardId,
                    a.F_AccountName,a.F_BankAccount,a.F_Bank,a.F_BankAddre,a.F_Address,
                    a.ProxyType,f.F_Account ReferenceAccount,f.F_RealName ReferenceName,
                    e.F_FullName ProxyCode,b.F_FullName F_Province,c.F_FullName F_City,d.F_FullName F_Area,a.F_IdAddress,
                    a.F_Id,a.F_NickName,a.F_HeadIcon,a.F_Gender,a.F_Birthday,a.F_Email,a.F_WeChat,
                    a.F_ManagerId,a.F_SecurityLevel,a.F_Signature,a.F_OrganizeId,a.F_DepartmentId,
                    a.F_RoleId,a.F_DutyId,a.F_IsAdministrator,a.F_SortCode,a.F_DeleteMark,
                    a.F_EnabledMark,a.F_Description,a.F_CreatorTime,a.F_CreatorUserId,a.F_LastModifyTime,
                    a.F_LastModifyUserId,a.F_DeleteTime,a.F_DeleteUserId,a.F_Pic,a.F_FatherPath,
                    a.F_FatherId,a.F_MemberMoney,a.ReferenceID,a.RCount,a.CurrentGroupID,
                    a.CurrentManagerType,a.CurrentManager,a.CumulativePoints,a.WelfarePrize,a.F_Installed
                    from sys_user a left join Sys_Area b on a.F_Province=b.F_Id 
                    left join Sys_Area c on a.F_City=c.F_Id 
                    left join Sys_Area d on a.F_Area=d.F_Id 
                    left join Sys_Area e on a.ProxyCode=e.F_Id
                    left join sys_user f on a.ReferenceID=f.F_Id where a.F_Id='" + keyValue + "'");
                UserEntity entity = new UserEntity();
                foreach (var obj in list)
                {
                    entity = obj;
                }
                return entity;
            }
        }

        #endregion

        public UserEntity FindEntityByFunc(Func<UserEntity, bool> predicate)
        {
            return IQueryable().OrderBy(u => u.F_CreatorTime).FirstOrDefault(predicate);
        }
        public UserEntity FindLastUserByCardid(string cardid)
        {
            var q = from u in dbcontext.Set<UserEntity>()
                    where !u.F_IsAdministrator.Value && u.F_CardId == cardid
                    orderby u.F_CreatorTime descending
                    select u;
            var lastUser = q.FirstOrDefault();
            return lastUser;
        }

    }
}
